package cn.anecansaitin.whimsy.common.capabilities.battle;

import cn.anecansaitin.whimsy.common.network.BattleModeAnimPack;
import cn.anecansaitin.whimsy.common.network.NetworkHelper;
import net.minecraft.nbt.CompoundTag;
import net.minecraft.world.entity.Entity;
import net.minecraft.world.entity.LivingEntity;
import net.neoforged.neoforge.network.PacketDistributor;
import software.bernie.geckolib.core.animatable.GeoAnimatable;

import javax.annotation.Nullable;

/**
 * 战斗控制器<br>
 * 控制技能释放、冷却等详细内容。<br>
 * 同时也控制着动画的执行。
 */
public interface IBattleController {
    void tick(LivingEntity livingEntity);

    /**
     * 处理按键输入，客户端与服务端均要调用一次<br>
     * 发包需要手动设置，通过重写sendKeyToServer来设置发包方式
     * @param livingEntity 输入指令的实体
     * @param key 输入的按键
     * @param action 按键的动作类型
     * @param modifiers 按键的修饰符
     * @return 结果标识，第一位表示是否发送服务端，第二位表示是否中止按键的原版处理，1表示true，其他表示false
     *
     * @see IBattleController#sendKeyToServer(LivingEntity, int, int, int)
     */
    byte[] keyInput(LivingEntity livingEntity, int key, int action, int modifiers);

    /**
     * 发送按键输入到服务端<br>
     * 仅当keyInput返回true时调用
     * @param livingEntity 发包的目标实体，通常是玩家
     * @param key 输入的按键
     * @param action 按键的动作类型
     * @param modifiers 按键的修饰符
     *
     * @see IBattleController#keyInput(LivingEntity, int, int, int)
     */
    void sendKeyToServer(LivingEntity livingEntity, int key, int action, int modifiers);

    /**
     * @return 动画执行对象
     */
    default IAnimController getAnimatable() {
        return (relatedEntity, controllerName, animName) -> {};
    }

    /**
     * @return 序列化控制器
     */
    CompoundTag serializeNBT();

    /**
     * @param nbt 反序列化NBT
     */
    void deserializeNBT(CompoundTag nbt);

    /**
     * @return 控制器ID
     */
    String getId();

    /**
     * @param entity 执行动画的实体
     * @param controllerName 动画控制器名称
     * @param animName 动画名称
     */
    default void triggerAnim(LivingEntity entity, String controllerName, String animName) {
        IAnimController controller = getAnimatable();

        if (entity.level().isClientSide) {
            controller.triggerAnim(entity, controllerName, animName);
        } else {
            NetworkHelper.send(PacketDistributor.TRACKING_ENTITY_AND_SELF.with(entity), new BattleModeAnimPack(entity.getId(), controllerName, animName));
        }
    }

    /**
     * 当退出战斗模式时触发<br>
     * 可用于清理实体状态
     * @param entity 退出战斗模式的实体
     */
    default void onQuitedMode(LivingEntity entity) {}
}
